<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Abstract class to provide a mechanism to uplaod a file and prepare it for use
 * by the LuckyFlag system.
 * 
 * @package CodeIgniter
 * @subpackage Libraries
 * @category Libraries
 * @author David Morris
 */
abstract class Uploader {
    
    protected $CI;
    protected $DB;
    protected $Table;       // The table we include our FK reference
    protected $Dir;         // Directory to store the file
    protected $Field;       // The field that is our FK reference in $Table
    
    public function __construct($Args)
    {
        extract($Args);
        $this->Table = $Table;
        $this->Dir = str_replace('//', '/', $Dir);
        $this->Field = $Field;
        $this->CI =& get_instance();
        $this->CI->load->database();
    }
    
    /**
     * Moves the file that has been uploaded from the specified file upload element.
     * It then proceeds to move the file from it's temporary location to a new location,
     * providing it with a clean and useable filename in the process.
     * 
     * If the upload is a success, the filename will be returned. Otherwise false.
     * 
     * @param string $formField The name of the file upload form element
     * @return mixed 
     */
    protected function moveFile($formField)
    {
        /**
         * If the file doesn't exist in the $_FILES array or there was an error return false
         * @todo change return false to an Exception??
         */        

        if(!array_key_exists($formField, $_FILES) || $_FILES[$formField]['error'] != UPLOAD_ERR_OK)
            return false;
        
        
        $pathInfo = pathinfo($_FILES[$formField]['name']);

        $newFileName = $this->createUsableFilename($pathInfo['filename'],$pathInfo['extension']);
        try {
            if(move_uploaded_file($_FILES[$formField]['tmp_name'], $this->Dir.'/'.$newFileName))
                return $newFileName;
        }
        catch(Exception $E) {
            echo $E->getMessage();
            return false;
        }
        return false;
        
    }
    
    /**
     * Creates a useable filename regardless of duplicate files based on the filename, extension
     * and the directory it is being moved to.
     * @param string $fileName the file name we want to test
     * @param string $fileExtension the extension for that file
     * @return string 
     */
    public function createUsableFilename($fileName, $fileExtension)
    {
        // clean our filename
        $fileName = str_replace(' ', '_', preg_replace("/[^a-zA-Z0-9\s]/", "", $fileName));
        if(!file_exists($this->Dir.'/'.$fileName.'.'.$fileExtension))
            return $fileName.'.'.$fileExtension;
        
        // Loop until we create a file that is unique
        $i = 1;
        while(file_exists($this->Dir.'/'.$fileName.'_'.++$i.'.'.$fileExtension));
        
        return $fileName.'_'.$i.'.'.$fileExtension;
    }
    
    /**
     * Wraps each element of the array (column names) with ` ready for an insert query
     * 
     * @param array $columnNames
     * @return string 
     */
    public function prepareColumns($columnNames = array())
    {
        return '`'.implode('`, `',$columnNames).'`';
    }
    
    
    /**
     * Abstract function to insert a new row with the new file id.
     */
    abstract public function insert($formField, $dbFieldsValues = array());
    
}
// END OF FILE